<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<!-- Casting SPELs in Lisp - Emacs Lisp Edition, a Comic Book
     Written by Conrad Barski, M.D., http://lisperati.com
     Edited by James A. Webb, http://uberkode.com -->

<head>

  <title>Casting SPELs in Lisp (26)</title>
  <meta http-equiv="content-type" content="text/html;charset=utf-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta name="author" content="James A. Webb" />
  <meta name="date" content="2007-09-16T00:00:00+00:00" />
  <meta name="keywords" content="Emacs, Lisp" />

</head>

<body>

<center>

<table cellspacing="10" width="500">
  <tr>
    <td>
      Let's try our new command:
    </td>
  </tr>
  <tr>
    <td>
<pre style="font-weight: bolder; color: darkblue">
  (weld 'chain 'bucket)
</pre>
    </td>
  </tr>
  <tr>
    <td>
<pre style="font-weight: bolder; color: darkgreen">
  ==> (you cannot weld like that -)
</pre>
    </td>
  </tr>
  <tr>
    <td>
      Oops... we don't have a bucket or chain, do we? ...and there's
      no welding machine around... oh well...
    </td>
  </tr>
  <tr>
    <td>
      Now let's create a command for dunking the chain and bucket in
      the well:
    </td>
  </tr>
  <tr>
    <td>
<pre style="font-weight: bolder; color: darkblue">
  (setq bucket-filled nil)

  (defun dunk (subject object)
    (cond ((and (eq location 'garden)
                (eq subject 'bucket)
                (eq object 'well)
                (have 'bucket)
                chain-welded)
           (setq bucket-filled 't) '(the bucket is now full of water))
          (t '(you cannot dunk like that -))))
</pre>
    </td>
  </tr>
  <tr>
    <td>
      Now if you paid attention, you probably noticed that this
      command looks a <i>lot</i> like the <tt>weld</tt> command...
      Both commands need to check the location, subject, and object,
      but they're different enough that we can't combine the
      similarities into a single function. Too bad...
    </td>
  </tr>
  <tr>
    <td>
      ...but since this is Lisp, we can do more than just write
      functions, we can cast SPELs! Let's create the following SPEL:
    </td>
  </tr>
  <tr>
    <td>
<pre style="font-weight: bolder; color: darkblue">
  (defspel game-action (command subj obj place &amp;rest rest)
    `(defspel ,command (subject object)
       `(cond ((and (eq location ',',place)
                    (eq ',subject ',',subj)
                    (eq ',object ',',obj)
                    (have ',',subj))
               ,@',rest)
              (t '(i cannot ,',command like that -)))))
</pre>
    </td>
  </tr>
  <tr>
    <td>
      Notice how ridiculously complex this SPEL is - It has more
      quotes, backquotes, commas and other weird symbols than you can
      shake a list at. More than that, it is a SPEL that actually
      casts <i>another</i> SPEL! Even experienced Lisp programmers
      would have to put some thought into creating a monstrosity like
      this (and in fact they would consider this SPEL to be inelegant
      and would go through some extra esoteric steps to make it
      better-behaved that we won't worry about here...)
    </td>
  </tr>
    <tr>
      <td align="center">
        &lt;&lt; <a href="casting-spels-emacs-1.html">begin</a>
        &lt; <a href="casting-spels-emacs-25.html">previous</a> - 
        <a href="casting-spels-emacs-27.html">next</a> &gt;
        <a href="casting-spels-emacs-35.html" >end</a> &gt;&gt;
    </td>
  </tr>
</table>

</center>

</body>

</html>